﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Core.IRepository;
using System.Linq.Expressions;
using Core.Queries;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using Core.Messages;
using Library.Extensions.Expressions;

namespace Repositories
{    
    public class Repository<TId, TEntity> : IRepository<TId, TEntity>
        where TEntity : class    
    {
        private readonly IQueryHelper<TEntity> queryHelper;
        private readonly DbContext Context;

        protected virtual DbSet<TEntity> Set 
        { 
            get 
            {
                return Context.Set<TEntity>();
            } 
        }

        public Repository(DbContext context, IQueryHelper<TEntity> queryHelper)
        {
            this.Context = context;
            this.queryHelper = queryHelper;
            this.queryHelper.Context = context;
        }

        public virtual TEntity FindBy(TId id)
        {
            return Set.Find(id);
        }

        public virtual void Add(TEntity entity)
        {            
            Set.Add(entity);
        }

        public virtual void Edit(TEntity entity)
        {
            Context.Entry(entity).State = System.Data.Entity.EntityState.Modified;
        }

        public void Delete(TEntity entity)
        {            
            Set.Remove(entity);
        }

        public void Delete(Expression<Func<TEntity, bool>> predicate)
        {
            var list = Set.Where(predicate).ToList();

            foreach (TEntity entity in list)
            {
                Set.Remove(entity);                
            }
        }

        public IList<TEntity> FindBy(Expression<Func<TEntity, bool>> predicate)
        {
            return Set.Where(predicate).ToList();
        }

        public virtual QueryResponse<TEntity> FindBy(Query<TEntity> query)
        {            
            var result = queryHelper.FindBy(Set, query);
            return result;
        }

        public IList<TEntity> FindAll()
        {
            return Set.ToList();
        }
    }
}
